import tkinter as tk
import math

from src import newton_method
from src.newton_method import equation

# 曲线控制点的初始坐标
control_points = [(0, 500), (166.666, 333.333), (333.333, 166.666), (500, 0)]

# 固定端点的索引
fixed_indexes = [0, 3]


class Curve:
    def __int__(self):
        print("a")

    def draw_curve(self,canvas):
        # 清空画布
        canvas.delete("all")

        # 绘制曲线
        canvas.create_line(control_points, smooth=True, width=2)

        # 绘制控制点
        for i, (x, y) in enumerate(control_points):
            if i in fixed_indexes:
                # 固定的端点使用不同的颜色
                canvas.create_oval(x - 5, y - 5, x + 5, y + 5, fill="green", outline="black")
            else:
                canvas.create_oval(x - 5, y - 5, x + 5, y + 5, fill="red", outline="black")

        for t in range(0, 11):
            t = t / 10.0
            print("t=:", t)
            x0 = 0
            solution = opt.newton(equation, x0, args=(a0, a1, a2, a3, y))
            x = ((1 - t) ** 3 * control_points[0][0] + 3 * (1 - t) ** 2 * t * control_points[1][0] +
                 3 * (1 - t) * t ** 2 * control_points[2][0] + t ** 3 * control_points[3][0])
            y = ((1 - t) ** 3 * control_points[0][1] + 3 * (1 - t) ** 2 * t * control_points[1][1] +
                 3 * (1 - t) * t ** 2 * control_points[2][1] + t ** 3 * control_points[3][1])
            print(x, y)

        x = 100

    def move_point(self,event):
        # 查找最接近鼠标点击位置的控制点，但不包括固定的端点
        closest_point = min([p for i, p in enumerate(control_points) if i not in fixed_indexes],
                            key=lambda p: ((p[0] - event.x) ** 2 + (p[1] - event.y) ** 2) ** 0.5)

        # 计算鼠标点击位置到曲线的距离
        distance = distance_to_curve(event.x, event.y)

        # 如果鼠标点击位置在曲线上，则输出点击的位置
        if distance < 5:
            print("Clicked on curve at position:", event.x, event.y)

        # 更新控制点的坐标为鼠标位置
        closest_point_index = control_points.index(closest_point)
        control_points[closest_point_index] = (event.x, event.y)

        # 重新绘制曲线
        draw_curve(canvas)

    def distance_to_curve(self,x, y):
        # 计算鼠标点击位置到曲线的最短距离
        min_distance = float("inf")

        for i in range(len(control_points) - 1):
            p1 = control_points[i]
            p2 = control_points[i + 1]

            # 计算线段的长度
            length = math.sqrt((p2[0] - p1[0]) ** 2 + (p2[1] - p1[1]) ** 2)

            # 计算鼠标点击位置到线段的距离
            distance = abs((p2[1] - p1[1]) * x - (p2[0] - p1[0]) * y + p2[0] * p1[1] - p2[1] * p1[0]) / length

            # 更新最短距离
            min_distance = min(min_distance, distance)

        return min_distance


# 创建主窗口
root = tk.Tk()
root.title("可拉动曲线")

# 创建画布
canvas = tk.Canvas(root, width=500, height=500)
canvas.pack()

# 绘制初始曲线
draw_curve(canvas)

# 绑定鼠标事件
canvas.bind("<B1-Motion>", move_point)

# 运行主循环
root.mainloop()
